/**
  路由鉴权：鉴权，项目当中路由能不能被有权限设置（某一个路由什么条件下不能访问、什么条件下能访问）
*/
import router from '@/router'
// 进度条插件
// @ts-ignore
import Nprogress from 'nprogress'
import 'nprogress/nprogress.css'
import useUserStore from './store/modules/user'
import { ElNotification } from 'element-plus'
import setting from './setting'

// 关闭进度条圆圈
Nprogress.configure({ showSpinner: setting.loadShowSpinner })

// 全局守卫：项目当中任意路由切换都会触发的钩子
// 访问某一个路由之前守卫
// 全局前置守卫
router.beforeEach(async (to: any, from: any, next: any) => {
  // to：你将要访问哪个路由
  // from：你从哪个路由过来的
  // next：路由放行函数

  // 用户数据小仓库
  const userStore = useUserStore()

  // 开启进度条
  Nprogress.start()

  // 获取token，去判断用户是否登录
  const token = userStore.token
  // 登录后，获取的用户名
  const username = userStore.username

  // 用户登录判断
  if (token) {
    // 有token
    // 登录成功，就不能访问login了
    if (to.path == '/login') {
      next({ path: '/' })
    } else {
      // 登录成功访问其余六个路由（登录排除）
      if (username) {
        // 放行
        next()
      } else {
        // 如果没有用户信息，在守卫这里发请求获取到了用户信息再放行
        // 这里为什么要用try...catch...   因为token会过期，你拿着过期的token肯定发请求失败了
        try {
          // 获取用户信息
          await userStore.userInfo()
          // 放行
          // 万一：刷新的时候是异步路由，有可能获取不到用户信息、异步路由还没有加载完毕，出现白色的效果
          next({ ...to })
        } catch (error) {
          // 提示用户
          warn()
          // token过期：获取不到用户信息
          // 用户手动修改本地存储token
          // 退出登录->用户相关的数据清空
          await userStore.logout()
          next({ path: 'login', query: { redirect: to.path } })
        }
      }
    }
  } else {
    // 无token
    // 用户未登录
    if (to.path == '/login') {
      next()
    } else {
      warn()
      next({
        path: '/login',
        query: {
          redirect: to.path,
        },
      })
    }
  }
})

const warn = () => {
  // 提示用户
  ElNotification({
    type: 'error',
    title: '提示',
    message: '登录过期，请重新登录。',
    duration: 3000,
  })
}

// 全局后置守卫
router.afterEach((to: any, from: any) => {
  // to:现在的路由信息  from：从哪个路由来的的路由信息
  // 完成进度条（关闭）
  Nprogress.done()

  // 修改页签title
  document.title = `${setting.title} - ${to.meta.title}`
})
